#pragma once
// -------------------------------------------------
// BlinKit - BlinKit Library
// -------------------------------------------------
//   File Name: frame_fetch_context.h
// Description: FrameFetchContext Class
//      Author: Ziming Li
//     Created: 2021-07-15
// -------------------------------------------------
// Copyright (C) 2021 MingYang Software Technology.
// -------------------------------------------------

/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef FrameFetchContext_h
#define FrameFetchContext_h

#include "blinkit/blink/renderer/core/fetch/fetch_context.h"
#include "blinkit/blink/renderer/core/fetch/resource_fetcher.h"
// BKTODO: #include "core/frame/csp/ContentSecurityPolicy.h"
#include "blinkit/blink/renderer/platform/heap/Handle.h"
#include "blinkit/blink/renderer/platform/network/ResourceRequest.h"
#include "blinkit/blink/renderer/wtf/PassOwnPtr.h"

namespace blink {

class Document;
class DocumentLoader;
class LocalFrame;
class ResourceError;
class ResourceLoader;
class ResourceResponse;
class ResourceRequest;

class FrameFetchContext final : public FetchContext
{
public:
    static ResourceFetcher* createContextAndFetcher(DocumentLoader* loader)
    {
        return ResourceFetcher::create(new FrameFetchContext(loader));
    }

    static void provideDocumentToContext(FetchContext& context, Document* document)
    {
        ASSERT(document);
        RELEASE_ASSERT(context.isLiveContext());
        static_cast<FrameFetchContext&>(context).m_document = document;
    }

    ~FrameFetchContext();

    bool isLiveContext() { return true; }

    void addAdditionalRequestHeaders(ResourceRequest&, FetchResourceType) override;
    void setFirstPartyForCookies(ResourceRequest&) override;
    // BKTODO: CachePolicy cachePolicy() const override;
    ResourceRequestCachePolicy resourceRequestCachePolicy(const ResourceRequest&, Resource::Type) const override;
    // BKTODO: void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority, int intraPriorityValue) override;
    void dispatchWillSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse) override;
    void dispatchDidLoadResourceFromMemoryCache(const Resource*) override;
    void dispatchDidReceiveResponse(unsigned long identifier, const ResourceResponse&, ResourceLoader* = 0) override;
    void dispatchDidReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength) override;
    void dispatchDidDownloadData(unsigned long identifier, int dataLength, int encodedDataLength)  override;
    void dispatchDidFinishLoading(unsigned long identifier, int64_t encodedDataLength) override;
    void dispatchDidFail(unsigned long identifier, const ResourceError &) override;

    bool shouldLoadNewResource(Resource::Type) const override;
    void willStartLoadingResource(ResourceRequest&) override;
    void didLoadResource(Resource*) override;

    void addResourceTiming(const ResourceTimingInfo&) override;
    bool canRequest(Resource::Type, const ResourceRequest&, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction) const override;
    bool allowResponse(Resource::Type, const ResourceRequest&, const KURL&, const ResourceLoaderOptions&) const override;

    bool isControlledByServiceWorker() const override;
    int64_t serviceWorkerID() const override;

    bool isMainFrame() const override;
    bool defersLoading() const override;
    bool isLoadComplete() const override;
    bool pageDismissalEventBeingDispatched() const override;
    bool updateTimingInfoForIFrameNavigation(ResourceTimingInfo*) override;
    void sendImagePing(const KURL&) override;
    void addConsoleMessage(const String&) const override;
    // BKTODO: SecurityOrigin* securityOrigin() const override;
    void upgradeInsecureRequest(FetchRequest&) override;
    void addClientHintsIfNecessary(FetchRequest&) override;
    void addCSPHeaderIfNecessary(Resource::Type, FetchRequest&) override;

#if 0 // BKTODO:
    ResourceLoadPriority modifyPriorityForExperiments(ResourceLoadPriority, Resource::Type, const FetchRequest&, ResourcePriority::VisibilityStatus) override;

    void countClientHintsDPR() override;
    void countClientHintsResourceWidth() override;
    void countClientHintsViewportWidth() override;
#endif

    std::shared_ptr<WebTaskRunner> loadingTaskRunner() const override;

    DECLARE_VIRTUAL_TRACE();

private:
    explicit FrameFetchContext(DocumentLoader*);
    inline DocumentLoader* ensureLoaderForNotifications() const;

    LocalFrame* frame() const; // Can be null
    void printAccessDeniedMessage(const KURL&) const;
    // BKTODO: ResourceRequestBlockedReason canRequestInternal(Resource::Type, const ResourceRequest&, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction, ContentSecurityPolicy::RedirectStatus) const;

    Document *m_document = nullptr;
    GCRefPtr<DocumentLoader> m_documentLoader;

    bool m_imageFetched : 1;
};

}

#endif
